
/* Generated by Interface Builder */

#import "Evp.h"
#import "Instrum.h"
#import <appkit/graphics.h>
#import "Statement.h"

@implementation Evp

+ initialize
{
   	image = [NXImage findImageNamed:"Evp"];
	riseOffset.x = 0;
	riseOffset.y = 26;
	ampOffset.x = 17;
	ampOffset.y = 41;
	durOffset.x = 38;
	durOffset.y = 41;
	decayOffset.x = 57;
	decayOffset.y = 26;
	outOffset.x = 29;
	outOffset.y = 8;
	
	return self;
}

- init
{
	written = NO;
	size.width = 80.;
	size.height = 80.;
	center.x = size.width/2.;
	center.y = size.height/2.;
	strcpy(type,"Evp");
	strcpy(name,"evp");
	
	amp = [[Param alloc] init:self :&ampOffset];
	rise = [[Param alloc] init:self :&riseOffset];
	dur = [[Param alloc] init:self :&durOffset];
	decay = [[Param alloc] init:self :&decayOffset];
	out = [[Param alloc] init:self :&outOffset];

	[rise setValue:".1"];	// set non-"1" default values
	[dur setValue:"p[1]"];	
	[decay setValue:".1"];	
	[amp setTitle:"Amp:"];
	[rise setTitle:"Rise:"];
	[dur setTitle:"Dur:"];
	[decay setTitle:"Decay:"];
	[out setTitle:"Out:"];
		
	paramList = [[List alloc] initCount:5];
	[paramList addObject:amp];
	[paramList addObject:rise];
	[paramList addObject:dur];
	[paramList addObject:decay];
	[paramList addObject:out];
	
	[Inst putUgenInList:self];
	
	return self;
}

- remove
{
	id cp,param;
	int i;
							// make sure not connected first 
	for(i = 0; i < ([paramList count]); i++) {	
		param = [paramList objectAt:i];
		if(cp = [param getConnectedParam]) 
			return 0;
	}
							// remove ugen from list
	[Inst removeUgenFromList:self];
	return self;
}

- (NXImage *)getImage
{
	return image;
}

- move:(NXPoint *)newloc
{
	location = *newloc;
	[amp move:&location];
	[rise move:&location];
	[dur move:&location];
	[decay move:&location];
	[out move:&location];
	return self;
}

- findParamAtPoint:(NXPoint *)point
{
	NXRect *rect;
	int i;
	id param;
	
	for(i = 0; i < [paramList count]; i++) {
		param = [paramList objectAt:i];
		rect = [param getRect];
		if(NXMouseInRect(point,rect,NO))
			return param;
	}
	//printf("no param found\n");
	return nil;
}

- writeUgen
{
	BOOL ai = NO;	// amplitude input ugen
	BOOL ri = NO;	// rise input ugen
	BOOL di = NO;	// decay input ugen
	char ampVar[10];
	char riseVar[10];
	char decayVar[10];
	char par[20];
	/* 	for amp, rise, & decay input params:
			see if there is input ugen
				if so, grab the output (ug?) and multiply it by this
					param value
				if not just use the param value
	 	after all params done, write relevant code into lists
			(declarations, assignments and loop statements)
			i.e. ug? = oscil(,,,,);
		go to output param connected ugen and call its "writeUgen"
	*/
	int i;
	int parent[4];
	id param;
	id ug;
	id nupar;
	char str[50];
	
	//printf("writing ugen %d\n",index);
	sprintf(str,"\tfloat ug%d;\n",index);
	[Inst putVarInList:str];
	sprintf(str,"\tfloat rise%d;\n",index);
	[Inst putVarInList:str];
	sprintf(str,"\tfloat decay%d;\n",index);
	[Inst putVarInList:str];
	sprintf(str,"\tfloat amp%d;\n",index);
	[Inst putVarInList:str];
	sprintf(str,"\tfloat dur%d;\n",index);
	[Inst putVarInList:str];
	sprintf(str,"\tfloat q%d[9];\n",index);
	[Inst putVarInList:str];
	sprintf(str,"\tfloat *f1_%d;\n",index);
	[Inst putVarInList:str];
	sprintf(str,"\tfloat *f2_%d;\n",index);
	[Inst putVarInList:str];
	sprintf(str,"\tfloat out%d;\n",index);
	[Inst putVarInList:str];

	for(i = 0; i < ([paramList count]-1); i++) {	
		param = [paramList objectAt:i];
		if(nupar = [param getConnectedParam]) {
			ug = [nupar getUgen];
			if([ug getWritten] == NO) { 
				parent[i] = [[ug writeUgen] getIndex];
			}
			else  {
				parent[i] = 0;
			}
			//printf("parent[%d] = %d\n",i,parent[i]);
		}
		else 
			parent[i] = 0;
		
	}
	
	strcpy(par,[[paramList objectAt:1] getValue]);
	if(par[0] == 'p' && par[1] == '[')
		sprintf(str,"\trise%d = %s;\n", index, par);
	else
		sprintf(str,"\trise%d = %.2f;\n", index, atof(par));
	[Inst putAssignInList:str];
	
	strcpy(par,[[paramList objectAt:2] getValue]);
	if(par[0] == 'p' && par[1] == '[')
		sprintf(str,"\tdur%d = %s;\n", index, par);
	else
		sprintf(str,"\tdur%d = %.2f;\n", index, atof(par));
	[Inst putAssignInList:str];
	
	strcpy(par,[[paramList objectAt:3] getValue]);
	if(par[0] == 'p' && par[1] == '[')
		sprintf(str,"\tdecay%d = %s;\n", index, par);
	else
		sprintf(str,"\tdecay%d = %.2f;\n", index, atof(par));
	[Inst putAssignInList:str];
	
	sprintf(str,"\tf1_%d = (float *)floc(2);\n", index);
	[Inst putAssignInList:str];
	sprintf(str,"\tf2_%d = f1_%d;\n", index,index);
	[Inst putAssignInList:str];
	
	if(parent[0]) { 	// amplitude input ugen	
		//printf("input ugen to evp amp\n");
		ai = YES;
		sprintf(str,"\tamp%d = %.2f;\n",index, 
			atof([[paramList objectAt:0] getValue]));
		[Inst putAssignInList:str];
		sprintf(str,"\tfloat ampai%d;\n",index);
		[Inst putVarInList:str];
		sprintf(str,"\t\tampai%d = amp%d * ug%d;\n",index,  
			index,parent[0]);
		[Inst putLoopInList:str];
	}
	else {				// amp preset or default
		//printf("amp preset or default\n");
		sprintf(str,"\tamp%d = %.2f;\n",index,atof([[paramList objectAt:0] getValue]));
		[Inst putAssignInList:str];
	}
	if(ai)
		sprintf(ampVar,"ampai%d",index);
	else
		sprintf(ampVar,"amp%d",index);
		
						// function 2 hardwired to rise function for now
	sprintf(str, "\tevset(dur%d,rise%d,decay%d,2,q%d);\n",index,index,index, index);
	[Inst putAssignInList:str];
	
					// output amplitude multiplier:
	strcpy(par,[[paramList objectAt:4] getValue]);
	if(par[0] == 'p' && par[1] == '[')
		sprintf(str,"\tout%d = %s;\n",index,par);
	else
		sprintf(str,"\tout%d = %.2f;\n", index, atof([[paramList objectAt:4] getValue]));
	[Inst putAssignInList:str];

	sprintf(str,"\t\tug%d = %s(i,f1_%d,f2_%d,q%d)*amp%d*out%d;\n", index,name, index,index,index,index,index);
	[Inst putLoopInList:str];
	written = YES;
	return self;	
}


@end
